JavaScript 设计模式之装饰器模式

Author Avatar
Klein 8月 27, 2018

介绍

  • 为对象添加新功能
  • 不改变其原有的结构和功能

实例

  • 手机壳

UML

演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Circle {
draw() {
console.log('画一个圆形');
}
}
class Decorator {
constructor(circle) {
this.circle = circle
}
draw() {
this.circle.draw()
this.setRedBorder(circle)
}
setRedBorder(circle) {
console.log('设置红色边框');
}
}

// 测试
let circle = new Circle()
circle.draw()
let dec = new Decorator()
dec.draw()

场景

  • ES7 装饰器
  • core-decorator

装饰器方法

readonly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function readonly(target, name, descriptor) {
descriptor.writable = false
return decorator
}

class Peson {
constructor() {
this.first = 'A'
this.last = 'B'
}
@readonly
name() {
return `first:${this.first} last:${this.last}`
}
}

let p = new Person()
console.log(p.name())
// first:A last:B
p.name = function () {
alert(100)
}
// 报错

log

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function log(target, name, descriptor) {
let oldValue = descriptor.value
descriptor.value = function () {
console.log(`calling ${name} width`, arguments);
return oldValue.apply(this, arguments)
}
return descriptor

}

class Math {
@log
add(a, b) {
return a + b
}
}

let math = new Math()
const result = math.add(2, 4)
console.log('result', result);

设计原则验证

  • 将现有对象和装饰器进行分离,两者独立存在
  • 符合开放封闭原则